#include <my_header.h>

/* Usage: ./26_线程安全 */

void *func(void *arg)
{
    time_t childTime;
    time(&childTime);
    //char *str=  ctime(&childTime);

    // 避免线程不安全 函数可能会出现竞争问题
    // 使用一些有线程安全的函数
    char buff[100];
    char *str = ctime_r(&childTime, buff);

    printf("child time = %s\n", str);
    sleep(5);
    printf("child time = %s\n", str);

    return NULL;
}

int main(void){                                  

    pthread_t tid;
    int ret_create = pthread_create(&tid, NULL, func, NULL);
    THREAD_ERROR_CHECK(ret_create, "pthread_create");

    sleep(3);
    time_t mainTime;
    time(&mainTime);

    char buff[100];
    // printf("man time =%s\n", ctime(&mainTime));
    printf("man time =%s\n", ctime_r(&mainTime, buff));

    int ret_join = pthread_join(tid, NULL);
    THREAD_ERROR_CHECK(ret_join, "pthread_join");

    return 0;
}

#if 0

在上述例子中的，子线程中的 str 是指向的区域是静态的，所以即使子线程没有作任何修改，但是因为主线程会调用ctime 修改静态区域的字符串，子线程两次输出的结构会有不同。

使用 ctime_r 可以避免这个问题，ctime_r 函数会增加一个额外指针参数，这个指针可以指向一个线程私有的数据，比如函数栈帧内，从而避免发生竞争问题
#endif
